package tableaux.rules;

import java.util.Collections;
import tableaux.BranchChanges;
import tableaux.Completion;
import tableaux.Branching;
//import tableaux.backjumping.DependencyImp;

import entities.concept.*;
import entities.*;

public class RuleOr {

	private OrConcept nextExp;
	private Completion dc;

	// private DataBranching br;

	public RuleOr(Completion dc) {
		super();
		this.dc = dc;
		// this.br = this.dc.getCurrentBranching();
	}

	public boolean isApplicable(Individual n) {
		// HashSet<Concept> unexp = new HashSet<Concept> ();
		// unexp.addAll(n.getLabels());
		// unexp.removeAll(n.getExpandedLabels());
		// if(unexp.size()<1){
		// return false;
		// }
		// for(Concept c : unexp){
		for (Concept c : n.getLabels()) {
			if (n.getExpandedLabels().contains(c)) {
				continue;
			}
			if (c instanceof OrConcept) {
				OrConcept oc = (OrConcept) c;
				// boolean repeat = false;
				// for(int i = 0; i<dc.getAllBranchesInPath().size(); i++){
				// Branching br = dc.getAllBranchesInPath().get(i);
				// if(br.getBranchInd().equals(n)
				// && br.getOriginalDisjunction().equals(c)){
				// System.out.println(oc+" already in queue, skip to: "+br.getOrder());
				// repeat = true;
				// break;
				// }
				// }
				// if(repeat){
				// continue;
				// }
				if (Collections.disjoint(n.getLabels(), oc.getConceptSet())) {
					// for "c1 or c2", neither of them are in the labels
					// if(DataCompletion.secondOrderAbsorption){
					// //if using second order absorption, there is >=1 concept
					// that is query feature or other concept
					// boolean safe = false;
					// for(Concept uc:oc.getConceptSet()){
					// if(!(uc instanceof DomainConcept) ||
					// DataCompletion.isQueryFeatureConcept(uc)){
					// safe = true;
					// break;
					// }
					// }
					// if(! safe){
					// continue;
					// }
					// }
					// if Ok, process
					this.nextExp = oc;
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * apply the or-rule, and generates a set of branches for the tableau to
	 * choose from. We will use branches. see completion.
	 * 
	 * @param n
	 * @return
	 */
	public boolean applyRule(Individual n) {
		boolean suc = false;
		Branching br = null;
		if (Collections.disjoint(n.getLabels(), this.nextExp.getConceptSet())) {
			// create new branches
			br = new Branching(n, this.nextExp);
			// this.setParentBranch(br, this.nextExp);
			suc = br.createBranch(null);
			// //debug
			// System.err.println("Or-branch created: "+n+
			// ", select: "+br.getLastChosenConcept()
			// +"; from "+br.getBranchConcepts());
			// //
			if (suc) {
				dc.setCurrentBranch(br);
			}
			boolean expadd = n.addExpandedLabels(this.nextExp);
			if (expadd && BranchChanges.getRecordingStatus()) {
				br.getBranchChanges().addToExpandedLabel(n, this.nextExp);
			}
		}
		return suc;
	}

	// //given an or concept OC, decide if OC is from some branch concept
	// private void setParentBranch(Branching cbr, OrConcept oc) {
	// Branching current = this.dc.getCurrentBranching();
	// if(current != null && current.getBranchConcepts().contains(oc)){
	// cbr.setFatherBranch(current);
	// //
	// System.out.println("son: "+cbr+"; father:"+current+"; because of "+oc);
	// return;
	// }
	// for(Branching sbr:this.dc.getAllBranchesInPath()){
	// if(sbr.getBranchConcepts().contains(oc)){
	// cbr.setFatherBranch(sbr);
	// break;
	// }
	// }
	// }

}
